//! 查询规划器模块
//!
//! 将SQL语句转换为逻辑执行计划

use crate::{Error, Result};
use sqlparser::ast::{Statement, ColumnDef, TableConstraint, DataType as SqlDataType, ColumnOption, ColumnOptionDef};
use std::collections::HashMap;

/// 查询规划器
#[derive(Debug)]
pub struct QueryPlanner {
    /// 表元数据缓存
    table_metadata: HashMap<String, TableMetadata>,
}

impl QueryPlanner {
    /// 创建新的查询规划器
    pub fn new() -> Self {
        Self {
            table_metadata: HashMap::new(),
        }
    }
    
    /// 创建逻辑执行计划
    /// TODO: 重构为使用真正的Statement AST
    pub fn create_logical_plan(&self, statements: Vec<Statement>) -> Result<LogicalPlan> {
        if statements.len() != 1 {
            return Err(Error::query_execution("暂不支持多语句执行"));
        }

        let statement = &statements[0];
        match statement {
            Statement::Query(query) => self.plan_select(query),
            Statement::Insert { .. } => self.plan_insert(statement),
            Statement::Update { .. } => self.plan_update(statement),
            Statement::Delete { .. } => self.plan_delete(statement),
            Statement::CreateTable { .. } => self.plan_create_table(statement),
            Statement::Drop { .. } => self.plan_drop_table(),
            _ => Err(Error::query_execution("不支持的SQL语句类型")),
        }
    }
    
    /// 规划简单SELECT语句
    fn plan_select_simple(&self, _sql: &str) -> Result<LogicalPlan> {
        // 简化实现：创建一个基础的表扫描计划
        Ok(LogicalPlan::TableScan {
            table_name: "default_table".to_string(),
            alias: None,
            projection: None,
        })
    }
    
    /// 规划简单INSERT语句
    fn plan_insert_simple(&self, _sql: &str) -> Result<LogicalPlan> {
        Err(Error::query_execution("INSERT语句规划暂未实现"))
    }

    /// 规划简单UPDATE语句
    fn plan_update_simple(&self, _sql: &str) -> Result<LogicalPlan> {
        Err(Error::query_execution("UPDATE语句规划暂未实现"))
    }

    /// 规划简单DELETE语句
    fn plan_delete_simple(&self, _sql: &str) -> Result<LogicalPlan> {
        Err(Error::query_execution("DELETE语句规划暂未实现"))
    }

    /// 规划简单CREATE TABLE语句
    fn plan_create_table_simple(&self, _sql: &str) -> Result<LogicalPlan> {
        Err(Error::query_execution("CREATE TABLE语句规划暂未实现"))
    }

    /// 规划简单DROP TABLE语句
    fn plan_drop_table_simple(&self, _sql: &str) -> Result<LogicalPlan> {
        Err(Error::query_execution("DROP TABLE语句规划暂未实现"))
    }

    /// 规划SELECT语句
    fn plan_select(&self, query: &sqlparser::ast::Query) -> Result<LogicalPlan> {
        // 解析SELECT语句的AST
        match &*query.body {
            sqlparser::ast::SetExpr::Select(select) => {
                // 获取表名（目前只支持单表查询）
                if select.from.len() != 1 {
                    return Err(Error::query_execution("暂不支持多表SELECT操作"));
                }

                // 从TableWithJoins中提取表名
                let table_name = if let sqlparser::ast::TableFactor::Table { name, .. } = &select.from[0].relation {
                    name.to_string()
                } else {
                    return Err(Error::query_execution("不支持的表类型"));
                };

                // 创建基础的表扫描计划
                let mut plan = LogicalPlan::TableScan {
                    table_name,
                    alias: None,
                    projection: None,
                };

                // 处理WHERE条件
                if let Some(where_expr) = &select.selection {
                    let predicate = self.convert_sql_expr_to_expression(where_expr)?;
                    plan = LogicalPlan::Filter {
                        input: Box::new(plan),
                        predicate,
                    };
                }

                // TODO: 处理SELECT列表、ORDER BY、GROUP BY等
                Ok(plan)
            }
            _ => Err(Error::query_execution("不支持的查询类型")),
        }
    }

    /// 规划INSERT语句
    fn plan_insert(&self, statement: &Statement) -> Result<LogicalPlan> {
        if let Statement::Insert {
            table_name,
            columns,
            source,
            ..
        } = statement {
            // 获取表名
            let table_name = table_name.to_string();

            // 处理列名（如果指定）
            let column_names = if columns.is_empty() {
                None
            } else {
                Some(columns.iter().map(|col| col.to_string()).collect())
            };

            // 处理VALUES子句
            if let Some(source) = source {
                if let sqlparser::ast::Query { body, .. } = source.as_ref() {
                    if let sqlparser::ast::SetExpr::Values(values) = body.as_ref() {
                        // 转换VALUES为表达式
                        let mut value_rows = Vec::new();
                        for row in &values.rows {
                            let mut expressions = Vec::new();
                            for expr in row {
                                expressions.push(self.convert_sql_expr_to_expression(expr)?);
                            }
                            value_rows.push(expressions);
                        }

                        return Ok(LogicalPlan::Insert {
                            table_name,
                            columns: column_names,
                            values: value_rows,
                        });
                    }
                }
            }

            Err(Error::query_execution("不支持的INSERT语句格式"))
        } else {
            Err(Error::query_execution("无效的INSERT语句"))
        }
    }

    /// 规划UPDATE语句
    fn plan_update(&self, statement: &Statement) -> Result<LogicalPlan> {
        if let Statement::Update {
            table,
            assignments,
            selection,
            ..
        } = statement {
            // 获取表名
            let table_name = table.to_string();

            // 转换赋值操作
            let mut update_assignments = Vec::new();
            for assignment in assignments {
                let column_name = assignment.id.iter()
                    .map(|ident| ident.value.clone())
                    .collect::<Vec<_>>()
                    .join(".");

                let value_expr = self.convert_sql_expr_to_expression(&assignment.value)?;

                update_assignments.push(Assignment {
                    column: column_name,
                    value: value_expr,
                });
            }

            // 转换WHERE条件（如果存在）
            let condition = if let Some(where_expr) = selection {
                Some(self.convert_sql_expr_to_expression(where_expr)?)
            } else {
                None
            };

            Ok(LogicalPlan::Update {
                table_name,
                assignments: update_assignments,
                condition,
            })
        } else {
            Err(Error::query_execution("不是UPDATE语句"))
        }
    }

    /// 规划DELETE语句
    fn plan_delete(&self, statement: &Statement) -> Result<LogicalPlan> {
        if let Statement::Delete {
            from,
            selection,
            ..
        } = statement {
            // 获取表名（目前只支持单表删除）
            if from.len() != 1 {
                return Err(Error::query_execution("暂不支持多表DELETE操作"));
            }

            // 从TableWithJoins中提取表名
            let table_name = if let sqlparser::ast::TableFactor::Table { name, .. } = &from[0].relation {
                name.to_string()
            } else {
                return Err(Error::query_execution("不支持的表类型"));
            };

            // 转换WHERE条件（如果存在）
            let condition = if let Some(where_expr) = selection {
                Some(self.convert_sql_expr_to_expression(where_expr)?)
            } else {
                None
            };

            Ok(LogicalPlan::Delete {
                table_name,
                condition,
            })
        } else {
            Err(Error::query_execution("不是DELETE语句"))
        }
    }

    /// 规划CREATE TABLE语句
    fn plan_create_table(&self, statement: &Statement) -> Result<LogicalPlan> {
        if let Statement::CreateTable {
            name,
            columns,
            constraints,
            ..
        } = statement {
            // 解析表名
            let table_name = name.to_string();

            // 解析列定义
            let mut column_definitions = Vec::new();
            for column in columns {
                let column_def = self.parse_column_definition(column)?;
                column_definitions.push(column_def);
            }

            // 解析约束
            let mut table_constraints = Vec::new();
            for constraint in constraints {
                let constraint_def = self.parse_table_constraint(constraint)?;
                table_constraints.push(constraint_def);
            }

            Ok(LogicalPlan::CreateTable {
                table_name,
                columns: column_definitions,
                constraints: table_constraints,
            })
        } else {
            Err(Error::query_execution("不是CREATE TABLE语句".to_string()))
        }
    }

    /// 规划DROP TABLE语句
    fn plan_drop_table(&self) -> Result<LogicalPlan> {
        // TODO: 基于AST实现真正的DROP TABLE规划
        Err(Error::query_execution("DROP TABLE语句规划暂未实现"))
    }

    /// 转换SQL表达式为内部表达式
    /// 支持字面值、列引用、二元操作等常用表达式类型
    fn convert_sql_expr_to_expression(&self, expr: &sqlparser::ast::Expr) -> Result<Expression> {
        match expr {
            // 字面值处理
            sqlparser::ast::Expr::Value(value) => {
                let literal = match value {
                    sqlparser::ast::Value::Number(n, _) => {
                        if n.contains('.') {
                            LiteralValue::Float(n.parse().map_err(|_| {
                                Error::query_execution("无效的浮点数")
                            })?)
                        } else {
                            LiteralValue::Integer(n.parse().map_err(|_| {
                                Error::query_execution("无效的整数")
                            })?)
                        }
                    }
                    sqlparser::ast::Value::SingleQuotedString(s) => LiteralValue::String(s.clone()),
                    sqlparser::ast::Value::DoubleQuotedString(s) => LiteralValue::String(s.clone()),
                    sqlparser::ast::Value::Boolean(b) => LiteralValue::Boolean(*b),
                    sqlparser::ast::Value::Null => LiteralValue::Null,
                    _ => return Err(Error::query_execution("不支持的字面值类型")),
                };
                Ok(Expression::Literal(literal))
            }

            // 列引用处理
            sqlparser::ast::Expr::Identifier(ident) => {
                Ok(Expression::Column {
                    name: ident.value.clone(),
                    table: None,
                })
            }

            // 复合标识符处理（如 table.column）
            sqlparser::ast::Expr::CompoundIdentifier(idents) => {
                if idents.len() == 2 {
                    Ok(Expression::Column {
                        name: idents[1].value.clone(),
                        table: Some(idents[0].value.clone()),
                    })
                } else if idents.len() == 1 {
                    Ok(Expression::Column {
                        name: idents[0].value.clone(),
                        table: None,
                    })
                } else {
                    Err(Error::query_execution("不支持的复合标识符格式"))
                }
            }

            // 二元操作处理
            sqlparser::ast::Expr::BinaryOp { left, op, right } => {
                let left_expr = Box::new(self.convert_sql_expr_to_expression(left)?);
                let right_expr = Box::new(self.convert_sql_expr_to_expression(right)?);

                let operator = match op {
                    sqlparser::ast::BinaryOperator::Plus => BinaryOperator::Plus,
                    sqlparser::ast::BinaryOperator::Minus => BinaryOperator::Minus,
                    sqlparser::ast::BinaryOperator::Multiply => BinaryOperator::Multiply,
                    sqlparser::ast::BinaryOperator::Divide => BinaryOperator::Divide,
                    sqlparser::ast::BinaryOperator::Eq => BinaryOperator::Equal,
                    sqlparser::ast::BinaryOperator::NotEq => BinaryOperator::NotEqual,
                    sqlparser::ast::BinaryOperator::Lt => BinaryOperator::LessThan,
                    sqlparser::ast::BinaryOperator::LtEq => BinaryOperator::LessThanOrEqual,
                    sqlparser::ast::BinaryOperator::Gt => BinaryOperator::GreaterThan,
                    sqlparser::ast::BinaryOperator::GtEq => BinaryOperator::GreaterThanOrEqual,
                    sqlparser::ast::BinaryOperator::And => BinaryOperator::And,
                    sqlparser::ast::BinaryOperator::Or => BinaryOperator::Or,
                    _ => return Err(Error::query_execution(format!("不支持的二元操作符: {:?}", op))),
                };

                Ok(Expression::BinaryOp {
                    left: left_expr,
                    operator,
                    right: right_expr,
                })
            }

            // 括号表达式处理
            sqlparser::ast::Expr::Nested(inner) => {
                self.convert_sql_expr_to_expression(inner)
            }

            // 一元操作处理（如负号）
            sqlparser::ast::Expr::UnaryOp { op, expr } => {
                match op {
                    sqlparser::ast::UnaryOperator::Minus => {
                        // 处理负数
                        let inner_expr = self.convert_sql_expr_to_expression(expr)?;
                        match inner_expr {
                            Expression::Literal(LiteralValue::Integer(n)) => {
                                Ok(Expression::Literal(LiteralValue::Integer(-n)))
                            }
                            Expression::Literal(LiteralValue::Float(f)) => {
                                Ok(Expression::Literal(LiteralValue::Float(-f)))
                            }
                            _ => {
                                // 对于非字面值，创建一个二元操作：0 - expr
                                Ok(Expression::BinaryOp {
                                    left: Box::new(Expression::Literal(LiteralValue::Integer(0))),
                                    operator: BinaryOperator::Minus,
                                    right: Box::new(inner_expr),
                                })
                            }
                        }
                    }
                    sqlparser::ast::UnaryOperator::Plus => {
                        // 正号，直接返回内部表达式
                        self.convert_sql_expr_to_expression(expr)
                    }
                    sqlparser::ast::UnaryOperator::Not => {
                        // NOT操作符，暂不支持
                        Err(Error::query_execution("NOT操作符暂不支持"))
                    }
                    _ => Err(Error::query_execution(format!("不支持的一元操作符: {:?}", op))),
                }
            }

            // 其他表达式类型暂不支持
            _ => Err(Error::query_execution(format!("不支持的表达式类型: {:?}", expr))),
        }
    }

    /// 解析列定义
    fn parse_column_definition(&self, column: &ColumnDef) -> Result<ColumnDefinition> {
        let name = column.name.to_string();
        let data_type = self.convert_sql_data_type(&column.data_type)?;

        let mut nullable = true;
        let mut default_value = None;
        let mut auto_increment = false;
        let mut primary_key = false;
        let mut unique = false;
        let mut check_constraint = None;

        // 解析列选项
        for option_def in &column.options {
            match &option_def.option {
                ColumnOption::NotNull => nullable = false,
                ColumnOption::Null => nullable = true,
                ColumnOption::Default(expr) => {
                    default_value = Some(format!("{}", expr));
                }
                ColumnOption::Unique { is_primary, .. } => {
                    if *is_primary {
                        primary_key = true;
                        nullable = false;
                    } else {
                        unique = true;
                    }
                }
                ColumnOption::Check(expr) => {
                    check_constraint = Some(format!("{}", expr));
                }
                _ => {
                    // 其他选项暂时忽略
                }
            }
        }

        // 检查是否为SERIAL类型（自增）
        if matches!(data_type, DataType::Serial) {
            auto_increment = true;
            nullable = false;
        }

        Ok(ColumnDefinition {
            name,
            data_type,
            nullable,
            default_value,
            auto_increment,
            primary_key,
            unique,
            check_constraint,
        })
    }

    /// 解析表约束
    fn parse_table_constraint(&self, constraint: &TableConstraint) -> Result<TableConstraintDefinition> {
        match constraint {
            // 处理UNIQUE约束，检查是否为主键
            TableConstraint::Unique { columns, name, is_primary, .. } => {
                let column_names: Vec<String> = columns
                    .iter()
                    .map(|ident| ident.value.clone())
                    .collect();

                // 根据is_primary字段判断是主键还是唯一约束
                let constraint_type = if *is_primary {
                    ConstraintType::PrimaryKey(column_names)
                } else {
                    ConstraintType::Unique(column_names)
                };

                Ok(TableConstraintDefinition {
                    name: name.as_ref().map(|n| n.value.clone()),
                    constraint_type,
                })
            }
            TableConstraint::Check { expr, name } => {
                Ok(TableConstraintDefinition {
                    name: name.as_ref().map(|n| n.value.clone()),
                    constraint_type: ConstraintType::Check(format!("{}", expr)),
                })
            }
            TableConstraint::ForeignKey { columns, foreign_table, referred_columns, name, .. } => {
                let column_names: Vec<String> = columns
                    .iter()
                    .map(|ident| ident.value.clone())
                    .collect();

                let referenced_columns: Vec<String> = referred_columns
                    .iter()
                    .map(|ident| ident.value.clone())
                    .collect();

                Ok(TableConstraintDefinition {
                    name: name.as_ref().map(|n| n.value.clone()),
                    constraint_type: ConstraintType::ForeignKey {
                        columns: column_names,
                        referenced_table: foreign_table.to_string(),
                        referenced_columns,
                    },
                })
            }
            _ => {
                // 其他约束类型暂不支持
                Ok(TableConstraintDefinition {
                    name: None,
                    constraint_type: ConstraintType::Check("true".to_string()),
                })
            }
        }
    }

    /// 转换SQL数据类型到内部数据类型
    fn convert_sql_data_type(&self, sql_type: &SqlDataType) -> Result<DataType> {
        match sql_type {
            SqlDataType::Int(_) | SqlDataType::Integer(_) => Ok(DataType::Integer),
            SqlDataType::BigInt(_) => Ok(DataType::BigInt),
            SqlDataType::Real => Ok(DataType::Real),
            SqlDataType::Float(_) => Ok(DataType::Float),
            SqlDataType::Double => Ok(DataType::Double),
            SqlDataType::Varchar(length) => {
                let len = length.as_ref().and_then(|l| {
                    if let sqlparser::ast::CharacterLength::IntegerLength { length, .. } = l {
                        Some(*length)
                    } else {
                        None
                    }
                });
                Ok(DataType::Varchar(len))
            }
            SqlDataType::Text => Ok(DataType::Text),
            SqlDataType::Boolean => Ok(DataType::Boolean),
            SqlDataType::Date => Ok(DataType::Date),
            SqlDataType::Timestamp(_, _) => Ok(DataType::Timestamp),
            SqlDataType::Custom(name, _) => {
                if name.to_string().to_uppercase() == "SERIAL" {
                    Ok(DataType::Serial)
                } else {
                    Err(Error::query_execution(format!("不支持的数据类型: {}", name)))
                }
            }
            _ => {
                Err(Error::query_execution(format!("不支持的数据类型: {:?}", sql_type)))
            }
        }
    }

}

impl Default for QueryPlanner {
    fn default() -> Self {
        Self::new()
    }
}

/// 表元数据
#[derive(Debug, Clone)]
pub struct TableMetadata {
    pub name: String,
    pub columns: Vec<ColumnMetadata>,
}

/// 列元数据
#[derive(Debug, Clone)]
pub struct ColumnMetadata {
    pub name: String,
    pub data_type: DataType,
    pub nullable: bool,
}

/// 数据类型
#[derive(Debug, Clone)]
pub enum DataType {
    Integer,
    BigInt,
    Float,
    Double,
    String,
    Boolean,
    Date,
    Timestamp,
    Varchar(Option<u64>),
    Text,
    Real,
    Serial,
    Decimal(Option<(u8, u8)>), // 精度和小数位数
}

/// 列定义
#[derive(Debug, Clone)]
pub struct ColumnDefinition {
    pub name: String,
    pub data_type: DataType,
    pub nullable: bool,
    pub default_value: Option<String>,
    pub auto_increment: bool,
    pub primary_key: bool,
    pub unique: bool,
    pub check_constraint: Option<String>,
}

/// 表约束定义
#[derive(Debug, Clone)]
pub struct TableConstraintDefinition {
    pub name: Option<String>,
    pub constraint_type: ConstraintType,
}

/// 约束类型
#[derive(Debug, Clone)]
pub enum ConstraintType {
    PrimaryKey(Vec<String>),
    ForeignKey {
        columns: Vec<String>,
        referenced_table: String,
        referenced_columns: Vec<String>,
    },
    Unique(Vec<String>),
    Check(String),
}

/// 逻辑执行计划
#[derive(Debug, Clone)]
pub enum LogicalPlan {
    /// 表扫描
    TableScan {
        table_name: String,
        alias: Option<String>,
        projection: Option<Vec<String>>,
    },
    /// 投影
    Projection {
        input: Box<LogicalPlan>,
        expressions: Vec<Expression>,
    },
    /// 过滤
    Filter {
        input: Box<LogicalPlan>,
        predicate: Expression,
    },
    /// 连接
    Join {
        left: Box<LogicalPlan>,
        right: Box<LogicalPlan>,
        join_type: JoinType,
        condition: Option<Expression>,
    },
    /// 聚合
    Aggregate {
        input: Box<LogicalPlan>,
        group_expressions: Vec<Expression>,
        aggregate_expressions: Vec<Expression>,
    },
    /// 排序
    Sort {
        input: Box<LogicalPlan>,
        expressions: Vec<SortExpression>,
    },
    /// 限制
    Limit {
        input: Box<LogicalPlan>,
        count: usize,
    },
    /// 创建表
    CreateTable {
        table_name: String,
        columns: Vec<ColumnDefinition>,
        constraints: Vec<TableConstraintDefinition>,
    },
    /// 插入数据
    Insert {
        table_name: String,
        columns: Option<Vec<String>>,
        values: Vec<Vec<Expression>>,
    },
    /// 更新数据
    Update {
        table_name: String,
        assignments: Vec<Assignment>,
        condition: Option<Expression>,
    },
    /// 删除数据
    Delete {
        table_name: String,
        condition: Option<Expression>,
    },
}

/// UPDATE语句中的赋值操作
#[derive(Debug, Clone)]
pub struct Assignment {
    /// 要更新的列名
    pub column: String,
    /// 新值表达式
    pub value: Expression,
}

/// 表达式
#[derive(Debug, Clone)]
pub enum Expression {
    /// 列引用
    Column {
        name: String,
        table: Option<String>,
    },
    /// 字面值
    Literal(LiteralValue),
    /// 二元操作
    BinaryOp {
        left: Box<Expression>,
        operator: BinaryOperator,
        right: Box<Expression>,
    },
    /// 通配符
    Wildcard,
}

impl Expression {
    /// 设置别名
    pub fn set_alias(&mut self, _alias: String) {
        // 简化实现，后续完善
    }
}

/// 字面值
#[derive(Debug, Clone)]
pub enum LiteralValue {
    Integer(i64),
    Float(f64),
    String(String),
    Boolean(bool),
    Null,
}

/// 二元操作符
#[derive(Debug, Clone, PartialEq)]
pub enum BinaryOperator {
    Plus,
    Minus,
    Multiply,
    Divide,
    Equal,
    NotEqual,
    LessThan,
    LessThanOrEqual,
    GreaterThan,
    GreaterThanOrEqual,
    And,
    Or,
    // 添加别名支持
    Add,
    Sub,
    Mul,
    Eq,
    Ne,
    Lt,
    Le,
    Gt,
    Ge,
}

/// 连接类型
#[derive(Debug, Clone)]
pub enum JoinType {
    Inner,
    Left,
    Right,
    Full,
}

/// 排序表达式
#[derive(Debug, Clone)]
pub struct SortExpression {
    pub expression: Expression,
    pub ascending: bool,
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::sql::parser::SqlParser;
    
    #[test]
    fn test_planner_creation() {
        let planner = QueryPlanner::new();
        assert!(true); // 基础创建测试
    }
    
    #[test]
    fn test_simple_select_planning() {
        let parser = SqlParser::new();
        let planner = QueryPlanner::new();

        let parse_result = parser.parse("SELECT id, name FROM users").unwrap();
        let plan = planner.create_logical_plan(parse_result.statements);

        assert!(plan.is_ok());

        // 简化测试：只验证能够创建计划
        if let Ok(LogicalPlan::TableScan { table_name, .. }) = plan {
            assert_eq!(table_name, "default_table");
        } else {
            panic!("期望TableScan计划");
        }
    }
}
